//  #include <rtthread.h>
//  //  #include "ioserver.h"
//  #include"sys_var_retain.h"
//  #include <string.h>
//  #include <errno.h>
//  #include <stdio.h>
//  //  #include <unistd.h>
//  #include <string.h>
//  #include <stdlib.h>
//  #include <time.h>
#include <mcu_def.h>

#include "modbus_server.h"
#include <libmodbus/modbus-private.h>
#include <libmodbus/modbus-rtu-private.h>

#if defined(_WIN32)
//  #include <ws2tcpip.h>
#elif defined(LWIP)
#include <sys/socket.h>
//#include <sys/time.h>
//  #include <netinet/in.h>
//  #include <arpa/inet.h>
#endif

//  unsigned short slave_id=1;
extern int debug ;
unsigned short slave_id = 1;
unsigned short MODBUS_SRV_STATUS;


void _modbus_rtu_server(modbus_server_t server)
{
    int size;
    modbus_t *ctx=server->ctx;
    modbus_rtu_t *ctx_rtu = (modbus_rtu_t *)ctx->backend_data;
    unsigned char *rxbuf = (unsigned char *)rt_malloc(256);  //���ͻ�����
    if(modbus_connect(ctx) == -1)
    {
        rt_kprintf("Connexion failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
    }
    size = rt_sprintf((char *)rxbuf, "\nmodbus server : id=%d\n", slave_id);
    rt_device_write(ctx_rtu->dev, 0, rxbuf, size);
    while(1)
    {
        int rc;
        modbus_set_slave(ctx, slave_id);
        rc = modbus_receive(ctx, rxbuf);
        if(rc >0)
        {
            /* rc is the query size */
            rt_thread_delay(ctx->ack_time);
            modbus_reply(server, rxbuf, rc,0);
            MODBUS_SRV_STATUS = 0;
        }
        else
        {
            MODBUS_SRV_STATUS = 2;
            /* Connection closed by the client or error */
            //        if(dev->net)
            //                break;
        }
    }
}

//	#ifdef WIN32
//	DWORD WINAPI device_server_modbus(LPVOID p)
//	//  void *device_server_modbus(void *p)
//	#else
void device_server_modbus(void *p)
//	#endif
{
    int i;
    int rc = 0;
    //    int length_to_read;
    modbus_server_t dev =(modbus_server_t ) p;
    modbus_t *ctx=dev->ctx;
    //      struct pport *port=dev->port;
    //    rt_uint32_t ch;
    //rt_thread_delay(1000);
    while(1)
    {
        ctx->backend->server_run(dev);
    }
}


modbus_server_t  modbus_server_init(modbus_server_t server,const char *name, const char *dev,int lendian,int swap,unsigned int baudrate,unsigned short dataBits,unsigned char stopBits,char parity)
{
//	    modbus_server_t server =(modbus_server_t ) rt_malloc(sizeof(struct modbus_server));
    server->read_single_coil=0;
    server->READ_HOLDING_REGISTER=0;
    server->WRITE_MULTIPLE_REGISTERS=0;
    server->write_single_coil=0;

    if(rt_strcmp(dev, "COM1") == 0)
    {
        rt_kprintf("\n\nMODBUS server to use COM1 , CONSOLE Closed.");
        rt_device_t t=rt_device_find(dev);
        rt_device_close(t);
        rt_console_set_device("no");
    }
//    if(!server->ctx.backend_data.device)
//    {
//        rt_kprintf("\n\nMODBUS server can't open COM1 , CONSOLE Closed.");
//        return 0;
//    }
    server->net=0;
    server->ctx=modbus_new_rtu(server->ctx,dev,baudrate,parity,dataBits,stopBits);
    if(!server->ctx)
    {
        rt_kprintf("\nmodbus_new_rtu Failed :%s\n",dev);
        return 0;
    }
    modbus_t *ctx=server->ctx;
    ctx->debug=0;

    if(lendian)
    {
        server->flag|=MODBUS_FLAG_LITTLE_ENDIAN;
    }
    else
    {
        server->flag&=~MODBUS_FLAG_LITTLE_ENDIAN;
    }
    if(swap)
    {
        server->flag|=MODBUS_FLAG_BYTE_SWAP;
    }
    else
    {
        server->flag&=~MODBUS_FLAG_BYTE_SWAP;
    }

//          modbus_set_slave(server->ctx, 1);

    rt_kprintf("\n modbus_server_init %s %d\n", __FILE__, __LINE__);

#ifdef WIN32
    HANDLE thread;
    DWORD  thread_id;
    thread = CreateThread(NULL,
                          0,
                          (LPTHREAD_START_ROUTINE)device_server_modbus,
                          server,
                          CREATE_SUSPENDED,
                          &thread_id);
    if(thread == NULL)
    {
//      throw(0);
        return 0;
    }
    ResumeThread(thread);

#else
    rt_thread_t t = rt_thread_create(name, device_server_modbus, server, 3072, PRIO_THREAD_DEVICE, RT_TICK_PER_SECOND / 10);
    if(!t)
    {
        rt_kprintf("system error");
        return 0;
    }
    rt_thread_startup(t);
#endif
    return server;

}

